package risk.control.application.utils;

import android.util.Log;

/**
 * Log 工具类
 * 1. 支持全局日志开关控制
 * 2. 自动获取调用类名作为 TAG
 * 3. 支持格式化字符串输出
 * 4. 支持长日志自动分段打印
 */
public class LogUtils {
    // 全局日志开关，发布时设为 false
    private static final boolean isLogEnabled = false;
    // 默认 TAG
    private static final String DEFAULT_TAG = "LogUtils";
    // 日志最大长度限制（Android 日志限制约4000字节）
    private static final int MAX_LOG_LENGTH = 3000;
    private static final String TagPrefix = "hm-->";

    // VERBOSE
    public static void v(String message) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.VERBOSE, tag, message, null);
        }
    }

    public static void v(String format, Object... args) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.VERBOSE, tag, String.format(format, args), null);
        }
    }

    // DEBUG
    public static void d(String message) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.DEBUG, tag, message, null);
        }
    }

    public static void d(String format, Object... args) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.DEBUG, tag, String.format(format, args), null);
        }
    }

    // INFO
    public static void i(String message) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.INFO, tag, message, null);
        }
    }

    public static void i(String format, Object... args) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.INFO, tag, String.format(format, args), null);
        }
    }

    // WARN
    public static void w(String message) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.WARN, tag, message, null);
        }
    }

    public static void w(String format, Object... args) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.WARN, tag, String.format(format, args), null);
        }
    }

    public static void w(Throwable tr) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.WARN, tag, "", tr);
        }
    }

    public static void w(String message, Throwable tr) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.WARN, tag, message, tr);
        }
    }

    // ERROR
    public static void e(String message) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.ERROR, tag, message, null);
        }
    }

    public static void e(String format, Object... args) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.ERROR, tag, String.format(format, args), null);
        }
    }

    public static void e(Throwable tr) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.ERROR, tag, "", tr);
        }
    }

    public static void e(String message, Throwable tr) {
        if (isLogEnabled) {
            String tag = getTag();
            log(Log.ERROR, tag, message, tr);
        }
    }

    /**
     * 获取调用类名作为 TAG
     */
    private static String getTag() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        if (stackTrace.length < 5) {
            return TagPrefix + DEFAULT_TAG;
        }
        StackTraceElement element = stackTrace[4];
        String className = element.getClassName();
        // 简化类名
        if (className.contains(".")) {
            className = className.substring(className.lastIndexOf(".") + 1);
        }
        // 去除内部类后面的$符号及后面内容
        if (className.contains("$")) {
            className = className.substring(0, className.indexOf("$"));
        }
        return TagPrefix + className;
    }

    /**
     * 处理日志输出，自动分段
     */
    private static void log(int priority, String tag, String message, Throwable tr) {
        if (!isLogEnabled) return;
        // 如果消息长度不大，直接打印
        if (message.length() < MAX_LOG_LENGTH) {
            if (tr == null) {
                Log.println(priority, tag, message);
            } else {
                Log.println(priority, tag, message + '\n' + Log.getStackTraceString(tr));
            }
            return;
        }

        // 长消息分段打印
        for (int i = 0, length = message.length(); i < length; i++) {
            int newline = message.indexOf('\n', i);
            newline = newline != -1 ? newline : length;
            do {
                int end = Math.min(newline, i + MAX_LOG_LENGTH);
                String part = message.substring(i, end);
                Log.println(priority, tag, part);
                i = end;
            } while (i < newline);
        }

        // 打印异常堆栈
        if (tr != null) {
            Log.println(priority, tag, Log.getStackTraceString(tr));
        }
    }
}
